import { ConstantEnum } from '@libs/common/enums';
import {
  BaseRepository,
  indexPaginateBuilder,
  showBuilderEntity,
} from '@libs/common/repository';
import { Inject, Injectable } from '@nestjs/common';
import { plainToInstance } from 'class-transformer';
import {
  DataSource,
  Equal,
  FindOptionsSelect,
  FindOptionsWhere,
  In,
  Repository,
} from 'typeorm';

import {
  CreateAccessLogDto,
  DeleteAccessLogDto,
  FindAccessLogDto,
  IndexAccessLogDto,
  ShowAccessLogDto,
  UpdateAccessLogDto,
} from './dto/access-log.dto';
import { AccessLog } from './entities/access-log.entity';
// import { ProviderKey } from './access-log.providers';

@Injectable()
export class AccessLogService extends BaseRepository {
  // 普通操作数据库方式，如果使用到了事务，需要使用事务操作数据库方式
  // @Inject(ProviderKey)
  // private repository: Repository<AccessLog>;

  constructor(
    @Inject(ConstantEnum.DB_DATA_SOURCE_MANAGER) dataSource: DataSource,
  ) {
    super(dataSource);
  }

  protected repository = this.getRepository(AccessLog);

  protected repositoryManager = () => this.getRepository(AccessLog);

  async index(dto: IndexAccessLogDto) {
    const res = await indexPaginateBuilder({
      dto,
      repository: this.repository,
    });
    return res;
  }

  show<D extends ShowAccessLogDto = ShowAccessLogDto>(dto: D) {
    return showBuilderEntity(this.repository, dto);
  }

  /** 只返回一条对象数据，如果存在多个只返回第一条 */
  async findOne(dto: FindAccessLogDto, select?: FindOptionsSelect<AccessLog>) {
    const entity = await this.findBase(dto);

    if (Array.isArray(entity) && entity.length > 0) {
      return entity[0];
    }

    return null;
  }

  /** 返回所有符合条件的数据 */
  find(dto: FindAccessLogDto, select?: FindOptionsSelect<AccessLog>) {
    return this.findBase(dto);
  }

  private findBase(
    dto: FindAccessLogDto,
    select?: FindOptionsSelect<AccessLog>,
  ) {
    const where: FindOptionsWhere<AccessLog> = {};
    // 更多 Find 条件查询
    if (dto.id) {
      where.id = dto.id;
    } else {
      return null;
    }

    return this.repository.find({ where });
  }

  async delete(dto: DeleteAccessLogDto) {
    const { id, ids } = dto;
    if (id) {
      await this.repositoryManager().delete({ id: Equal(id) });
    } else if (ids) {
      await this.repositoryManager().delete({ id: In(ids) });
    }
    return;
  }

  update(dto: UpdateAccessLogDto | UpdateAccessLogDto[]) {
    const dtos = Array.isArray(dto) ? dto : [dto];
    const entities = plainToInstance(AccessLog, dtos);

    return this.repositoryManager().save(entities);
  }

  create(dto: CreateAccessLogDto | CreateAccessLogDto[]) {
    const entity = this.repositoryManager().create(
      plainToInstance(AccessLog, dto),
    );

    return this.repositoryManager().insert(entity);
  }

  import() {
    // CODE
  }

  export() {
    // CODE
  }

  switch(id: string, status: boolean) {
    // status 需要在 entity 中定义, 如果没有不需要这个接口
    // return this.repository.update({ id }, { status });
  }
}
